package com.itheima.project.handler.impl;

import com.itheima.project.constant.security.OauthCacheConstant;
import com.itheima.project.constant.security.OauthConstant;
import com.itheima.project.handler.CacheTokenHandler;
import com.itheima.project.handler.RefreshTokenHandler;
import com.itheima.project.utils.EmptyUtil;
import com.itheima.project.utils.ExceptionsUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpRequestMethodNotSupportedException;

import java.security.Principal;
import java.util.Map;

/**
 * @ClassName RefreshTokenHandlerImpl.java
 * @Description 刷新令牌处理实现
 */
@Slf4j
@Component
public class RefreshTokenHandlerImpl implements RefreshTokenHandler {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    TokenEndpoint tokenEndpoint;

    @Autowired
    CacheTokenHandler cacheTokenHandler;

    @Override
    public Boolean refreshToken(Principal principal, Map<String, String> parameters) {
        Boolean flag = false;
        //通过jti获得refreshToken，parameters，principal
        String jti = parameters.get(OauthConstant.JTI_KEY);
        RBucket<String> refreshTokenBucket = redissonClient.getBucket(OauthCacheConstant.REFRESH_TOKEN + jti);
        String refreshToken = refreshTokenBucket.get();
        if (EmptyUtil.isNullOrEmpty(refreshToken)){
            return flag;
        }
        OAuth2AccessToken oAuth2AccessToken = null;
        try {
            oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        } catch (HttpRequestMethodNotSupportedException e) {
            log.error("刷新令牌出错：{}", ExceptionsUtil.getErrorMessageWithNestedException(e));
            return flag;
        }
        cacheTokenHandler.cacheToken(oAuth2AccessToken);
        return flag;
    }
}
